home *** CD-ROM | disk | FTP | other *** search
- /*********************************
- * *
- * Visual Shell v1.17 10/92 *
- * *
- * by Torsten Jürgeleit *
- * *
- * tree part *
- * *
- *********************************/
-
- /* Includes */
-
- #include "includes.h"
- #include "imports.h"
- #include "protos.h"
-
- /* Show directory tree */
-
- VOID
- action_tree(VOID)
- {
- struct FileRequest *freq = &file_req[active_freq];
- struct TreeRequest *treq = &tree_req;
- struct TreeNode *old_cursor_tnode = NULL;
- BYTE *name = &file2_buffer[0];
- SHORT error;
-
- if ((error = build_device_name(name, freq->fr_DirLock)) ==
- VSH_STATUS_NORMAL) {
- hcomp_freq_cursor(freq);
- print_info_line(INFO_LINE_MODE_EMPTY);
- print_fkey_text(FKEY_MODE_NONE);
- if ((error = build_dir_tree(treq, name)) == VSH_STATUS_NORMAL) {
-
- /* Get our position in dir tree */
- name = BaseName(&freq->fr_DirName[0]);
- do {
- old_cursor_tnode = get_tree_node_by_name(treq, old_cursor_tnode,
- name);
- } while (Strcmp(&freq->fr_DirName[0], build_tnode_path_name(treq,
- old_cursor_tnode)));
- treq->tr_DirNode = old_cursor_tnode;
- treq->tr_CursorNode = &treq->tr_RootNode;
- treq->tr_XPos = 0;
- treq->tr_YPos = 0;
- print_tree_page(treq);
- do {
- ULONG signals = Wait(SIGF_INTUITION | SIGF_ACTION);
-
- if (signals & SIGF_INTUITION) { /* timing events from Intuition */
- struct IntuiMessage *msg;
-
- if (msg = (struct IntuiMessage *)
- GetMsg(con_window->UserPort)) {
- ULONG class = msg->Class;
-
- ReplyMsg((struct Message *)msg);
- switch (class) {
- case REFRESHWINDOW :
- print_tree_page(treq);
- break;
- case INTUITICKS :
- if (auto_repeat) {
- scroll_tree_req();
- }
- break;
- }
- }
- }
- if (signals & SIGF_ACTION) {
- switch (action) {
- case VSH_ACTION_NUM_ENTER :
- error = read_new_dir(freq, build_tnode_path_name(treq,
- treq->tr_CursorNode), READ_DIR_MODE_NO_OUTPUT);
- break;
- case VSH_ACTION_SPEED_SEARCH :
- old_cursor_tnode = treq->tr_CursorNode;
- if (get_input(INPUT_MODE_TREQ_ENTRY, &gadget_buffer[0])
- == FALSE) {
- move_treq_cursor(treq, old_cursor_tnode,
- MOVE_MODE_NORMAL);
- }
- print_fkey_text(FKEY_MODE_QUIT_ONLY);
- print_treq_status(treq);
- break;
- case VSH_ACTION_SCROLL_LEFT :
- case VSH_ACTION_SCROLL_RIGHT :
- case VSH_ACTION_SCROLL_UP :
- case VSH_ACTION_SCROLL_DOWN :
- scroll_tree_req();
- break;
- }
- }
- } while (action != VSH_ACTION_QUIT && action != VSH_ACTION_ESC &&
- action != VSH_ACTION_NUM_ENTER);
- }
- print_status(VSH_STATUS_FREE_TREE);
- free_dir_tree(treq);
- status = error;
- draw_requesters(DRAW_MODE_CLEAR);
- }
- }
- /* Displaye tree page */
-
- VOID
- print_tree_page(struct TreeRequest *treq)
- {
- SetAPen(con_rport, (LONG)COLOR0);
- RectFill(con_rport, (LONG)(BORDER_LEFT - 2), (LONG)
- (BORDER_TOP_HIDDEN - 1), (LONG)(vsh_width - BORDER_RIGHT
- + 1), (LONG)(cli_vpos - 3));
- draw_line(COLOR1, (USHORT)2, (USHORT)(BORDER_TOP_HIDDEN - 2),
- (USHORT)(vsh_width - 3), (USHORT)(BORDER_TOP_HIDDEN - 2));
- move_treq_cursor(treq, treq->tr_DirNode, MOVE_MODE_NO_CURSOR);
- print_fkey_text(FKEY_MODE_QUIT_ONLY);
- print_treq_status(treq);
- }
- /* Build directory tree */
-
- SHORT
- build_dir_tree(struct TreeRequest *treq, BYTE *dev_name)
- {
- struct TreeNode *tnode = &tree_req.tr_RootNode;
- SHORT error;
-
- strcpy(&treq->tr_DeviceName[0], dev_name);
- strcpy(&treq->tr_DirName[0], dev_name);
- NewList((struct List *)&tnode->tn_List); /* init root node */
- tnode->tn_Node.mln_Succ = NULL;
- tnode->tn_Node.mln_Pred = NULL;
- tnode->tn_ParentNode = NULL; /* indicates root node */
- tnode->tn_XPos = 0;
- tnode->tn_YPos = 0;
- tnode->tn_MaxDirs = 1;
- strcpy(&tnode->tn_Name[0], dev_name);
- enable_abort = 1;
- do {
- if ((error = read_tree_dirs(treq, tnode)) == VSH_STATUS_NORMAL) {
- tnode = get_next_unscanned_tree_node(treq, tnode);
- }
- } while (tnode && error == VSH_STATUS_NORMAL);
- enable_abort = 0;
- return(error);
- }
- /* Get all subdirectories in given directory */
-
- SHORT
- read_tree_dirs(struct TreeRequest *treq, struct TreeNode *parent_tnode)
- {
- struct MinList *list = &parent_tnode->tn_List;
- struct TreeNode *tnode;
- BPTR lock;
- BYTE *path = &path1_buffer[0];
- BOOL keepon = TRUE;
- SHORT error = VSH_STATUS_NORMAL;
-
- if (!(lock = quiet_lock(&treq->tr_DirName[0], (LONG)SHARED_LOCK))) {
- error = VSH_ERROR_LOCK_FAILED;
- } else {
- if (Examine(lock, fib) == DOSFALSE) { /* enter dir */
- error = VSH_ERROR_EXAMINE_FAILED;
- } else {
-
- /* Scan loop */
- do {
-
- /* ESC pressed ? */
- if (CheckAbort(NULL)) {
- error = VSH_ERROR_ABORTED;
- } else {
-
- /* Get next dir entry */
- if (ExNext(lock, fib) == DOSFALSE) {
- if (IoErr() != ERROR_NO_MORE_ENTRIES) {
- error = VSH_ERROR_EXNEXT_FAILED;
- }
- keepon = FALSE;
- } else {
-
- /* New dir found */
- if (fib->fib_DirEntryType > 0) {
- if (!(tnode = (struct TreeNode *)AllocMem((LONG)
- sizeof(struct TreeNode), MEMF_PUBLIC |
- MEMF_CLEAR))) {
- error = VSH_ERROR_OUT_OF_MEM;
- } else {
-
- /* Build new directory tree node */
- NewList((struct List *)&tnode->tn_List);
- tnode->tn_XPos = parent_tnode->tn_XPos + 1;
- tnode->tn_YPos = 0;
- tnode->tn_MaxDirs = 1;
- tnode->tn_MaxDepth = tnode->tn_XPos + 1;
- tnode->tn_ParentNode = parent_tnode;
- strcpy(&tnode->tn_Name[0], &fib->fib_FileName[0]);
- AddTail((struct List *)list, (struct Node *)tnode);
-
- /* Print full dir name in status line */
- if ((error = build_path_name_from_lock(path, lock))
- == VSH_STATUS_NORMAL) {
- print_dos_status(DOS_MODE_TREE, path, NULL);
- }
- }
- }
- }
- }
- } while (error == VSH_STATUS_NORMAL && keepon == TRUE);
- }
- UnLock(lock);
- }
- return(error);
- }
- /* Get node of next unscanned directory in tree */
-
- struct TreeNode *
- get_next_unscanned_tree_node(struct TreeRequest *treq,
- struct TreeNode *parent_tnode)
- {
- struct TreeNode *tnode;
- ULONG max_dirs, max_depth;
- BYTE *ptr, *path = &treq->tr_DirName[0];
- BOOL keepon = TRUE;
-
- tnode = (struct TreeNode *)parent_tnode->tn_List.mlh_Head; /* try to go deeper */
- if (tnode->tn_Node.mln_Succ) { /* list not empty ? */
- tnode->tn_YPos = parent_tnode->tn_YPos;
- TackOn(path, &tnode->tn_Name[0]);
- } else {
- do { /* else go back */
- ptr = BaseName(path); /* go one dir back */
- if (*(ptr - 1) == '/') {
- ptr--;
- }
- *ptr = '\0';
- tnode = (struct TreeNode *)parent_tnode->tn_Node.mln_Succ; /* next dir in list */
- if (tnode->tn_Node.mln_Succ) { /* not end of list ? */
- tnode->tn_YPos = parent_tnode->tn_YPos + parent_tnode->tn_MaxDirs;
- TackOn(path, &tnode->tn_Name[0]);
- keepon = FALSE;
- } else {
- if (!(parent_tnode = parent_tnode->tn_ParentNode)) { /* root reached ? */
- tnode = NULL;
- keepon = FALSE;
- } else {
- max_dirs = 0; /* count dirs and get max depth in branch of tree */
- max_depth = 0;
- for (tnode = (struct TreeNode *)parent_tnode->tn_List.mlh_Head;
- tnode->tn_Node.mln_Succ; tnode = (struct TreeNode *)
- tnode->tn_Node.mln_Succ) {
- max_dirs += tnode->tn_MaxDirs;
- if (tnode->tn_MaxDepth > max_depth) {
- max_depth = tnode->tn_MaxDepth;
- }
- }
- parent_tnode->tn_MaxDirs += max_dirs - 1;
- parent_tnode->tn_MaxDepth = max_depth;
- }
- }
- } while (keepon == TRUE);
- }
- return(tnode);
- }
- /* Free directory tree */
-
- VOID
- free_dir_tree(struct TreeRequest *treq)
- {
- struct TreeNode *tnode = &treq->tr_RootNode;
- struct MinList *list;
-
- do {
- list = &tnode->tn_List;
- if ((struct MinList *)list->mlh_TailPred != list) { /* list not empty ? */
- tnode = (struct TreeNode *)list->mlh_Head;
- } else {
- if (tnode = tnode->tn_ParentNode) {
- FreeMem((APTR)RemHead((struct List *)&tnode->tn_List), (LONG)
- sizeof(struct TreeNode));
- }
- }
- } while (tnode);
- }
- /* Scroll directory tree */
-
- VOID
- scroll_tree_req(VOID)
- {
- struct TreeRequest *treq = &tree_req;
- struct TreeNode *tnode2, *tnode = treq->tr_CursorNode;
- USHORT columns = treq->tr_Columns, rows = treq->tr_Rows;
- ULONG cxpos, cypos, xpos = treq->tr_XPos, ypos = treq->tr_YPos,
- max_dirs = treq->tr_RootNode.tn_MaxDepth,
- max_depth = treq->tr_RootNode.tn_MaxDirs;
-
- do {
- switch (scroll_flag) {
- case 1 : /* scroll up */
- tnode = get_prev_column_tree_node(tnode);
- break;
- case 2 : /* scroll down */
- tnode = get_next_column_tree_node(tnode);
- break;
- case 4 : /* scroll left */
- if (tnode2 = tnode->tn_ParentNode) {
- tnode = tnode2;
- }
- break;
- case 8 : /* scroll right */
- tnode2 = (struct TreeNode *)tnode->tn_List.mlh_Head;
- if (tnode2->tn_Node.mln_Succ) {
- tnode = tnode2;
- } else {
- tnode = get_next_column_tree_node(tnode);
- }
- break;
- }
- if (tnode != treq->tr_CursorNode) {
- cxpos = tnode->tn_XPos;
- cypos = tnode->tn_YPos;
- if (cxpos <= xpos) {
- xpos = cxpos;
- if (xpos) {
- xpos--;
- }
- } else {
- if (cxpos >= (xpos + columns - 1)) {
- xpos = cxpos - columns + 1;
- if ((xpos + columns) < max_dirs) {
- xpos++;
- }
- }
- }
- if (cypos <= ypos) {
- ypos = cypos;
- if (ypos) {
- ypos--;
- }
- } else {
- if (cypos >= (ypos + rows - 1)) {
- ypos = cypos - rows + 1;
- if ((ypos + rows) < max_depth) {
- ypos++;
- }
- }
- }
- hcomp_treq_cursor(treq);
- treq->tr_CursorNode = tnode;
- if (xpos != treq->tr_XPos || ypos != treq->tr_YPos) {
- treq->tr_XPos = xpos;
- treq->tr_YPos = ypos;
- print_dir_tree(treq);
- }
- hcomp_treq_cursor(treq);
- print_treq_status(treq);
- }
- } while (vsh_scroll_speed == SCROLL_SPEED_FAST && auto_repeat);
- }
- /* Build full path name for given node in dir tree */
-
- BYTE *
- build_tnode_path_name(struct TreeRequest *treq,
- struct TreeNode *search_tnode)
- {
- struct TreeNode *tnode2, *tnode = &treq->tr_RootNode;
- ULONG xpos = search_tnode->tn_XPos, ypos = search_tnode->tn_YPos;
- BYTE *path = &path1_buffer[0];
-
- strcpy(path, &tnode->tn_Name[0]);
- while (tnode != search_tnode) {
- tnode2 = (struct TreeNode *)tnode->tn_Node.mln_Succ;
- if (tnode2 && tnode2->tn_Node.mln_Succ && tnode2->tn_YPos <= ypos) {
- tnode = tnode2; /* next entry in list */
- tnode2 = (struct TreeNode *)tnode->tn_Node.mln_Succ;
- if (!tnode2->tn_Node.mln_Succ || tnode2->tn_YPos > ypos) {
- TackOn(path, &tnode->tn_Name[0]);
- }
- } else {
- tnode2 = (struct TreeNode *)tnode->tn_List.mlh_Head;
- if (tnode2->tn_Node.mln_Succ && tnode2->tn_XPos <= xpos) {
- tnode = tnode2; /* go deeper */
- tnode2 = (struct TreeNode *)tnode->tn_Node.mln_Succ;
- if (!tnode2->tn_Node.mln_Succ || tnode2->tn_YPos > ypos) {
- TackOn(path, &tnode->tn_Name[0]);
- }
- }
- }
- }
- return(path);
- }
- /* Jump to an specified entry in dir tree */
-
- VOID
- jump_to_treq_entry(BYTE *name, USHORT mode)
- {
- struct TreeRequest *treq = &tree_req;
- struct TreeNode *tnode;
-
- if (mode == JUMP_MODE_FIRST) {
- tnode = NULL;
- } else {
- tnode = treq->tr_CursorNode;
- }
- if ((tnode = get_tree_node_by_name(treq, tnode, name)) || (tnode =
- get_tree_node_by_name(treq, (struct TreeNode *)NULL, name))) {
- move_treq_cursor(treq, tnode, MOVE_MODE_NORMAL);
- }
- }
- /* Move cursor to specified entry in dir tree */
-
- VOID
- move_treq_cursor(struct TreeRequest *treq, struct TreeNode *tnode,
- USHORT mode)
- {
- ULONG xpos = treq->tr_XPos, ypos = treq->tr_YPos,
- cxpos = tnode->tn_XPos, cypos = tnode->tn_YPos;
- USHORT columns = treq->tr_Columns, rows = treq->tr_Rows,
- max_depth = treq->tr_RootNode.tn_MaxDepth,
- max_dirs = treq->tr_RootNode.tn_MaxDirs;
-
- if (tnode != treq->tr_CursorNode || mode == MOVE_MODE_NO_CURSOR) {
- if (mode != MOVE_MODE_NO_CURSOR) {
- hcomp_treq_cursor(treq);
- }
- if (cxpos <= xpos || cxpos >= (xpos + columns - 1) || cypos <= ypos ||
- cypos >= (ypos + rows - 1)) {
- if (max_depth > columns) {
- if (cxpos <= (columns / 2)) {
- xpos = 0;
- } else {
- xpos = cxpos - columns / 2;
- if ((xpos + columns) > max_depth) {
- xpos -= (xpos + columns) - max_depth;
- }
- }
- }
- if (max_dirs > rows) {
- if (cypos <= (rows / 2)) {
- ypos = 0;
- } else {
- ypos = cypos - rows / 2;
- if ((ypos + rows) > max_dirs) {
- ypos -= (ypos + rows) - max_dirs;
- }
- }
- }
- treq->tr_XPos = xpos;
- treq->tr_YPos = ypos;
- print_dir_tree(treq);
- } else {
- if (mode == MOVE_MODE_NO_CURSOR) {
- print_dir_tree(treq);
- }
- }
- treq->tr_CursorNode = tnode;
- hcomp_treq_cursor(treq);
- }
- }
- /* Get tree node by given name */
-
- struct TreeNode *
- get_tree_node_by_name(struct TreeRequest *treq, struct TreeNode *tnode,
- BYTE *name)
- {
- struct TreeNode *tnode2;
- ULONG len = strlen(name);
- BYTE *ptr, *path = &treq->tr_DirName[0];
- BOOL keepon, searching = TRUE;
-
- if (! len) {
- tnode = &treq->tr_RootNode;
- strcpy(path, &tnode->tn_Name[0]);
- } else {
- if (! tnode) {
- tnode = &treq->tr_RootNode;
- strcpy(path, &tnode->tn_Name[0]);
- if (! Strncmp(&tnode->tn_Name[0], name, len)) {
- searching = FALSE; /* found */
- }
- }
- while (searching == TRUE) {
- tnode2 = (struct TreeNode *)tnode->tn_List.mlh_Head; /* try to go deeper */
- if (tnode2->tn_Node.mln_Succ) { /* list not empty ? */
- tnode = tnode2;
- TackOn(path, &tnode->tn_Name[0]);
- } else {
- keepon = TRUE;
- do { /* else go back */
- ptr = BaseName(path); /* go one dir back */
- if (*(ptr - 1) == (BYTE)'/') {
- ptr--;
- }
- *ptr = '\0';
- tnode2 = (struct TreeNode *)tnode->tn_Node.mln_Succ; /* next dir in list */
- if (tnode2->tn_Node.mln_Succ) { /* not end of list ? */
- tnode = tnode2;
- TackOn(path, &tnode->tn_Name[0]);
- keepon = FALSE;
- } else {
- if (!(tnode = tnode->tn_ParentNode)) { /* root reached ? */
- tnode = NULL;
- keepon = FALSE;
- searching = FALSE; /* not found */
- }
- }
- } while (keepon == TRUE);
- }
- if (searching == TRUE) {
- if (! Strncmp(&tnode->tn_Name[0], name, len)) {
- searching = FALSE;
- }
- }
- }
- }
- return(tnode);
- }
-